#include "./BSP/KEY/key_manager.h"
#include "./BSP/LED/led_manager.h"
#include "./BSP/BEEP/beep.h"

#include "stdio.h"

/* -------------------------------------------- 按键IO初始化 ---------------------------------------------- */

static void InitKeyIo(void)
{ 
    GPIO_InitTypeDef gpio_init_struct;
    
    /* 开启时钟 */
    KEY0_GPIO_CLK_ENABLE();                                     /* KEY0时钟使能 */
    KEY1_GPIO_CLK_ENABLE();                                     /* KEY1时钟使能 */

    /* GPIO初始化 */
    gpio_init_struct.Pin = KEY0_GPIO_PIN;                       /* KEY0引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(KEY0_GPIO_PORT, &gpio_init_struct);           /* KEY0引脚模式设置,上拉输入 */

    gpio_init_struct.Pin = KEY1_GPIO_PIN;                       /* KEY1引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(KEY1_GPIO_PORT, &gpio_init_struct);           /* KEY1引脚模式设置,上拉输入 */
}

/* -------------------------------------------- 按键状态读取函数 ------------------------------------------- */

cotKeyState_e ReadKey0(void)
{
    return GPIO_GET_KEY0() ? COT_KEY_ON : COT_KEY_OFF;
}

cotKeyState_e ReadKey1(void)
{
    return GPIO_GET_KEY1() ? COT_KEY_ON : COT_KEY_OFF;
}

/* -------------------------------------------- 按键回调函数 ----------------------------------------------- */

/* KEY0键回调函数 */
static void OnKey0Press(cotKey_t key)
{
    if (!cotKey_IsLongPress(key))   /* 判断是否触发了长按 */
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS))     /* 按下首次触发 */
        {
            printf("KEY0 pressed\r\n");
        }

        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN))    /* 识别到短按 */
        {
            cotLed_Toggle(LED_0);
            printf("KEY0 released\r\n");
        }
    }
    else
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS))     /* 识别到长按 */
        {
            cotLed_Toggle(LED_0);
            printf("KEY0 long press detected\r\n");
        }

        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN))    /* 长按松开 */
        {
            printf("KEY0 long press released\r\n");  
        }
    }
}

/* KEY1键回调函数 */
static void OnKey1Press(cotKey_t key)
{
    /* 连击复合模式：按下时间超过阈值时变为普通模式，否则为连击模式 */
    uint8_t clickCount = cotKey_GetClickCount(key);
    
    if (clickCount > 0)
    {
        /* 连击模式 - 按下时间在阈值内 */
        switch (clickCount)
        {
            case 1:  /* 单击 */
                cotLed_Toggle(LED_0);
                BEEP_TOGGLE();
                printf("Key2 single click\r\n");
                break;
            case 2:  /* 双击 */
                cotLed_TwinkleWithCount(LED_0, 200, 2, COT_LED_OFF);
                printf("Key2 double click\r\n");
                break;
            case 3:  /* 三击 */
                cotLed_TwinkleWithCount(LED_0, 200, 3, COT_LED_OFF);
                printf("Key2 triple click\r\n");
                break;
            case 4:  /* 四击 */
                cotLed_TwinkleWithCount(LED_0, 200, 4, COT_LED_OFF);
                printf("Key2 quadruple click\r\n");
                break;
            default:
                if (clickCount > 4)
                {
                    cotLed_TwinkleWithCount(LED_0, 200, clickCount, COT_LED_OFF);
                    printf("Key2 clicked %d times\r\n", clickCount);
                }
                break;
        }
    }
    else
    {
        /* 普通模式 - 按下时间超过阈值 */
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN))    /* 松开触发 */
        {
            cotLed_TwinkleWithCount(LED_0, 100, 10, COT_LED_OFF);   /* 快速闪烁10次表示长按 */
            printf("Key2 long press (>1000ms)\r\n");
        }
    }
}

/* -------------------------------------------- 按键模块API函数 -------------------------------------------- */

void FML_KEY_Init(void)
{
    static cotKeyCfg_t s_keyTable[KEY_MAX_NUM] =
    {
        {.pfnKeyState = ReadKey0},
        {.pfnKeyState = ReadKey1},
    };

    /* 初始化按键IO */
    InitKeyIo();

    /* 初始化COT按键模块 */
    cotKey_Init(s_keyTable, KEY_MAX_NUM);
    
    /* 注册按键回调 */
    cotKey_Listen(KEY0, OnKey0Press);
    cotKey_Listen(KEY1, OnKey1Press);

    /* 配置按键模式 */
    cotKey_ConfigLongPressMode(KEY0, 1500, 500);                                /* KEY0配置为长按模式，1500ms长按，500ms重复触发 */
    cotKey_ConfigClickCompMode(KEY1, 200, 1000, COT_KEY_TRIGGER_WAY_LOSSEN);    /* KEY1配置为连击复合模式，200ms连击间隔，1000ms超时，松开触发 */
}
